#!/usr/bin/python
#Takes a .ply file from, say, http://graphics.stanford.edu/data/3Dscanrep/, and turns it into a
#section of a .scn file used by Kinyk
#

class Point(object):
 """A simple 3-float point"""
 def __init__(self, x=0.0, y=0.0, z=0.0):
  self.x = x
  self.y = y
  self.z = z

class Triangle(object):
 """A simple triangle"""
 def __init__(self, p1, p2, p3):
  self.p1 = p1
  self.p2 = p2
  self.p3 = p3
 def toString(self):
  output1 = "corner1[%f,%f,%f]" % (self.p1.x, self.p1.y, self.p1.z)
  output2 = "corner2[%f,%f,%f]" % (self.p2.x, self.p2.y, self.p2.z)
  output3 = "corner3[%f,%f,%f]" % (self.p3.x, self.p3.y, self.p3.z)
  return output1 + output2 + output3


def read_ply(filename):
 #open the file
 ply_file = open(filename)
 #check the magic header
 line = ply_file.readline()
 if(line[:3] != 'ply'):
  print "This is not a ply file - the header is wrong, it should be 'ply'"
  return
 line = ply_file.readline() #this should be 'format ascii 1.0'
 line = ply_file.readline() #this should be 'comment'
 line = ply_file.readline() #this should be 'element vertex <num vertices>'
 words = line.split()
 if(words[0] == 'element' and words[1] == 'vertex'):
  num_vertices = int(words[2])
 else:
  print "This is not a ply file - line 4 should be 'element vertex <num vertices>'"
  return
 line = ply_file.readline() #this should be 'property float x'
 line = ply_file.readline() #this should be 'property float y'
 line = ply_file.readline() #this should be 'property float z'
 line = ply_file.readline() #this should be 'element face <num elements>'
 words = line.split()
 if(words[0] == 'element' and words[1] == 'face'):
  num_faces = int(words[2])
 else:
  print "This is not a ply file - line 8 should be 'element face <num faces>'"
  return
 line = ply_file.readline() #this should be 'property list uchar int vertex_indices'
 line = ply_file.readline() #this should be 'end_header'
 if(line != 'end_header\n'):
  print "Couldn't find end of header"
  return
 print "Read ply '%s' with %d vertices and %d faces" % (filename, num_vertices, num_faces)
 print "Reading %d vertices..." % num_vertices
 vertices = []
 for i in range(num_vertices):
  line = ply_file.readline() #this should be 3 floats
  words = line.split()
  x = float(words[0])
  y = float(words[1])
  z = float(words[2])
  p = Point(x, y, z)
  vertices.append(p)
 print "done."
 print "Reading %d faces..." % num_faces
 faces = []
 for i in range(num_faces):
  line = ply_file.readline() #this should be 4 ints
  words = line.split()
  if(words[0] == '3'): #we have a 3-point face - a triangle
   p1_index = int(words[1])
   p2_index = int(words[2])
   p3_index = int(words[3])
   t = Triangle(vertices[p1_index], vertices[p2_index], vertices[p3_index])
   faces.append(t)
  else:
   print "Unrecognized face - all faces should be triangles, cause I'm lazy"
   print line
   return
 print "done."
 return faces
  
  
import sys
if __name__ == '__main__':
 # Parse the input 
 # If there aren't enough args, show usage and exit
 if(len(sys.argv) < 2):
  print """Usage: ply_to_scn <inputfilename> <outputfilename>"""
  exit()
 # get the file
 inputfile_name = sys.argv[1]
 outputfile_name = sys.argv[2]
 #read the faces
 faces = read_ply(inputfile_name)
 print "Now have an array of triangular faces of size %d" % len(faces)
 print "Outputting the faces to a .scn file (%s)" % outputfile_name
 #output the faces
 output_file = open(outputfile_name, 'w')
 for i in range(len(faces)):
  output_file.write("triangle{material ply_material " + faces[i].toString() + "}\n")
 output_file.close()
 
